package bancosys.tec.services.api;

import java.math.BigDecimal;

import jmine.tec.services.api.ServiceAssertionFailedError;
import jmine.tec.services.api.ServiceProperties;
import jmine.tec.services.api.ServiceValidationExecutionException;
import jmine.tec.services.impl.ServicesImplMessages;
import bancosys.tec.persist.base.enumx.IntValuedEnum;
import bancosys.tec.persist.base.enumx.StringValuedEnum;
import bancosys.tec.persist.controller.PersistenceEnabledController;
import bancosys.tec.utils.date.Date;

public abstract class AbstractTestService<C extends PersistenceEnabledController> extends AbstractService<C> {

    public static final double DEFAULT_PRECISION = 0.001;

    public static final double VALOR_FINANCEIRO_PRECISION = 0.001;

    public AbstractTestService() {
        super();
    }

    public AbstractTestService(ServiceProperties serviceProperties) {
        super(serviceProperties);
    }

    /**
     * Comparação de BigDecimals (não lança erro)
     * 
     * @return <code>true</code> se os valores forem considerados iguais, <code>false</code> caso contrário.
     */
    protected boolean isEquals(BigDecimal expected, BigDecimal got) {
        return this.isEquals(expected, got, DEFAULT_PRECISION);
    }

    /**
     * Comparação de BigDecimals (não lança erro)
     * 
     * @return <code>true</code> se os valores forem considerados iguais, <code>false</code> caso contrário.
     */
    protected boolean isEquals(BigDecimal expected, BigDecimal got, double precision) {
        try {
            ServiceAssert.assertEquals(null, expected, got, precision);
            return true;
        } catch (ServiceAssertionFailedError e) {
            return false;
        }
    }

    /**
     * Comparação de BigDecimals
     */
    protected void assertEqualsExact(String fieldName, BigDecimal expected, BigDecimal got) {
        ServiceAssert.assertEquals(fieldName, expected, got, 0.0);
    }

    protected void assertEquals(BigDecimal expected, BigDecimal got, double precision) throws ServiceValidationExecutionException {
        ServiceAssert.assertEquals(null, expected, got, precision);
    }

    protected void assertEquals(String fieldName, BigDecimal expected, BigDecimal got, double precision)
            throws ServiceValidationExecutionException {
        ServiceAssert.assertEquals(fieldName, expected, got, precision);
    }

    protected void assertEquals(BigDecimal expected, BigDecimal got) throws ServiceValidationExecutionException {
        this.assertEquals(null, expected, got);
    }

    protected void assertEquals(String fieldName, BigDecimal expected, BigDecimal got) throws ServiceValidationExecutionException {
        ServiceAssert.assertEquals(fieldName, expected, got, DEFAULT_PRECISION);
    }

    /**
     * Compração de datas
     */
    protected void assertEquals(Date expected, Date got) throws ServiceValidationExecutionException {
        ServiceAssert.assertEquals(null, expected, got);
    }

    /**
     * Comparação de Enum (IntValuedEnum)
     */
    protected void assertEquals(String fieldName, IntValuedEnum expected, IntValuedEnum got) throws ServiceValidationExecutionException {
        ServiceAssert.assertEquals(fieldName, expected, got);
    }

    /**
     * Comparação de Enum (IntValuedEnum)
     */
    protected void assertEquals(IntValuedEnum expected, IntValuedEnum got) throws ServiceValidationExecutionException {
        this.assertEquals(null, expected, got);
    }

    /**
     * Comparação de Enum (StringValuedEnum)
     */
    protected void assertEquals(String fieldName, StringValuedEnum expected, StringValuedEnum got)
            throws ServiceValidationExecutionException {
        ServiceAssert.assertEquals(fieldName, expected, got);
    }

    /**
     * Comparação de Enum (StringValuedEnum)
     */
    protected void assertEquals(StringValuedEnum expected, StringValuedEnum got) throws ServiceValidationExecutionException {
        this.assertEquals(null, expected, got);
    }

    /**
     * Comparação de Enum (StringValuedEnum)
     */
    protected void assertEquals(String fieldName, Object expected, Object got) throws ServiceValidationExecutionException {
        ServiceAssert.assertEquals(fieldName, expected, got);
    }

    /**
     * Comparação de Enum (StringValuedEnum)
     */
    protected void assertEquals(Object expected, Object got) throws ServiceValidationExecutionException {
        ServiceAssert.assertEquals(expected, got);
    }

    /**
     * Verifica se a condição é true
     */
    protected void assertTrue(boolean condition) throws ServiceValidationExecutionException {
        ServiceAssert.assertTrue(condition);
    }

    /**
     * Verifica se a condição é true
     */
    protected void assertTrue(String fieldName, boolean condition) throws ServiceValidationExecutionException {
        ServiceAssert.assertTrue(fieldName, condition);
    }

    /**
     * Verifica se a condição é false
     */
    protected void assertFalse(boolean condition) throws ServiceValidationExecutionException {
        ServiceAssert.assertFalse(condition);
    }

    /**
     * Verifica se a condição é false
     */
    protected void assertFalse(String fieldName, boolean condition) throws ServiceValidationExecutionException {
        ServiceAssert.assertFalse(fieldName, condition);
    }

    /**
     * Verifica se não é Null
     * 
     * @param fieldName {@link String}
     * @param obj {@link Object}
     * @throws ServiceValidationExecutionException
     */
    protected void assertNotNull(String fieldName, Object obj) throws ServiceValidationExecutionException {
        ServiceAssert.assertNotNull(fieldName, obj);
    }

    /**
     * Verifica se não é Null
     * 
     * @param obj {@link Object}
     * @throws ServiceValidationExecutionException
     */
    protected void assertNotNull(Object obj) throws ServiceValidationExecutionException {
        ServiceAssert.assertNotNull(obj);
    }

    /**
     * Verifica se é Null
     * 
     * @param obj {@link Object}
     * @throws ServiceValidationExecutionException
     */
    protected void assertNull(Object obj) throws ServiceValidationExecutionException {
        ServiceAssert.assertNull(obj);
    }

    /**
     * Verifica se é Null
     * 
     * @param obj {@link Object}
     * @throws ServiceValidationExecutionException
     */
    protected void assertNull(String fieldName, Object obj) throws ServiceValidationExecutionException {
        ServiceAssert.assertNull(fieldName, obj);
    }

    /**
     * Falha o teste
     */
    protected void fail() {
        ServiceAssert.fail();
    }

    /**
     * Falha o teste com a msg passada como parâmetro
     * 
     * @param msg {@link String}
     * @deprecated use localized message holder
     */
    @Deprecated
    protected void fail(String msg) {
        ServiceAssert.fail(ServicesImplMessages.ASSERT_FAILED_NOT_INTERNATIONALIZED.create(msg));
    }
}
